﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Web;

using Concret;
using ORM;
using static Common;
using static Constants;
using static DataLogic;

public class View : HandlerBase
{
	/// <summary>
	/// 查看图片(中等尺寸)
	/// </summary>
	/// <param name="photo"></param>
	/// <returns></returns>
	public dynamic view(Photo photo)
	{
		if (photo == null) throw new Error("图片不存在");
		return photoStruct(photo);
	}

	/// <summary>
	/// 查看前一张图片(中等尺寸)
	/// </summary>
	/// <param name="photo"></param>
	/// <param name="owner">导游范围：如果对应图片的目录，则是在此目录中的所有图片，否则就是此图片用户的所有图片</param>
	/// <returns></returns>
	public dynamic prev(Photo photo, long owner)
	{
		if (photo == null) throw new Error("图片资源失效了，试下重新登录再访问");
		IEnumerable<Photo> photos;
		if (owner == photo.Dir_Val.Id)
			photos = photo.Dir_Val.Dir__Photo().OrderBy(p => p.Id);
		else
			photos = photo.User_Val.User__Photo().OrderBy(p => p.Id);

		photo = photos.FirstOrDefault(p => p.Id > photo.Id);
		if (photo == null) photo = photos.First();

		return photoStruct(photo);
	}

	/// <summary>
	/// 查看后一张图片(中等尺寸)
	/// </summary>
	/// <param name="photo"></param>
	/// /// <param name="owner">导游范围：如果对应图片的目录，则是在此目录中的所有图片，否则就是此图片用户的所有图片</param>
	/// <returns></returns>
	public dynamic next(Photo photo, long owner)
	{
		if (photo == null) throw new Error("图片资源失效了，试下重新登录再访问");
		IEnumerable<Photo> photos;
		if (owner == photo.Dir_Val.Id)
			photos = photo.Dir_Val.Dir__Photo().OrderByDescending(p => p.Id);
		else
			photos = photo.User_Val.User__Photo().OrderByDescending(p => p.Id);

		photo = photos.FirstOrDefault(p => p.Id < photo.Id);
		if (photo == null) photo = photos.First();

		return photoStruct(photo);
	}

	/// <summary>
	/// 变换图片
	/// </summary>
	/// <param name="photo"></param>
	/// <param name="type">1：顺时针旋转，2：水平镜像</param>
	/// <returns></returns>
	public dynamic transform(Photo photo, byte type)
	{
		if (photo == null) throw new Error("图片资源失效了，试下重新登录再访问");

		var me = GetCurrentUser(DbOp);
		if (photo.User_Val != me && !me.IsAdmin()) throw new Error("你不是此图片的作者，也不是管理员");

		var file = HttpContext.Current.Server.MapPath(photo.Path_Val);
		using (var image = Image.FromFile(file))
		{
			image.RotateFlip(type == 1 ? RotateFlipType.Rotate90FlipNone : RotateFlipType.RotateNoneFlipX);
			image.Save(file);
		}

		var thumb = file.Replace(@"\attachment\", @"\thumb\");
		if (File.Exists(thumb))
			using (var image = Image.FromFile(thumb))
			{
				image.RotateFlip(type == 1 ? RotateFlipType.Rotate90FlipNone : RotateFlipType.RotateNoneFlipX);
				image.Save(thumb);
			}

		photo.Updated_Val = Helper.NewId;
		photo.Update();

		notify(photo);

		return photoStruct(photo);
	}

	/// <summary>
	/// 通知前端更新图片显示
	/// </summary>
	/// <param name="photo"></param>
	void notify(Photo photo)
	{
		var disposed = new List<WebSocket>();

		AdvancedLock.EnterShareBlock(() =>
		{
			foreach (var socket in WebSockets)
				try
				{
					socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes($"photo:{photo.Id}:src:{photo.Path_Val}?thumb={ThumbQ.Detail}&update={photo.Updated_Val ?? 0}")), WebSocketMessageType.Text, true, CancellationToken.None);
				}
				catch
				{
					disposed.Add(socket);
				}
		});

		if (disposed.Count > 0)
			AdvancedLock.EnterMutexBlock(() => disposed.ForEach(socket => WebSockets.Remove(socket)));
	}

	dynamic photoStruct(Photo photo)
	{
		var image = Image.FromFile(HttpContext.Current.Server.MapPath(photo.Path_Val));
		var rotate = image.PropertyItems.SingleOrDefault(p => p.Id == 0x112)?.Value[0];
		var (w, h) = rotate == 6 || rotate == 8 ? (image.Height, image.Width) : (image.Width, image.Height);
		image.Dispose();

		var me = GetCurrentUser(DbOp);
		return new
		{
			id = photo.Id.ToString(),
			remark = photo.Remark_Val ?? photo.Title_Val,
			full = photo.Path_Val,
			url = $"{photo.Path_Val}?thumb={ThumbQ.Detail}&update={photo.Updated_Val ?? 0}",
			width = w,
			height = h,
			mine = photo.User_Val == me || me.IsAdmin(),
			dir = photo.Dir_Val.Title_Val,
			user = photo.User_Val.Uname_Val,
		};
	}
}